package ae.pcfc.cldos.online.common.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class LoggerHandler {
	private static Logger log = null;

	public LoggerHandler() {
	}

	/**
	 * A join point is in the service layer if the method is defined in a type
	 * in the ae.pcfc.cldos.online.common.delegate package or any sub-package
	 * under that.
	 */
	@Pointcut("within(ae.pcfc.cldos.online.common.delegate..*)")
	public void inBusinessDelegateLayer() {
	}

	/**
	 * A join point is in the service layer if the method is defined in a type
	 * in the service or facade or manager packages or any sub-packages under
	 * that.
	 */
	@Pointcut("within(ae.pcfc.cldos.online.common.facade..*) || within(ae.pcfc.cldos.online.common.manager..*)")
	public void inServiceLayer() {
	}

	/**
	 * A join point is in the data access layer if the method is defined in a
	 * type in the ae.pcfc.cldos.online.common.dao package or any sub-package
	 * under that.
	 */
	@Pointcut("within(ae.pcfc.cldos.online.clddb.domain..*) || within(ae.pcfc.cldos.online.tscdb.domain..*) || within(ae.pcfc.cldos.online.prdb.domain..*)")
	public void inDomainLayer() {
	}

	/**
	 * A join point is in the data access layer if the method is defined in a
	 * type in the ae.pcfc.cldos.online.common.dao package or any sub-package
	 * under that.
	 */
	@Pointcut("within(ae.pcfc.cldos.online.common.clddb.dao..*) || within(ae.pcfc.cldos.online.common.clddb.dao..*)")
	public void inDataAccessLayer() {
	}

	@Before("inBusinessDelegateLayer() || inServiceLayer()|| inDomainLayer ()|| inDataAccessLayer()")
	public void logBeforeInfo(JoinPoint joinPoint) throws Throwable {

		log = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
		if (log.isInfoEnabled()) {
			Signature sig = joinPoint.getSignature();

//			Object[] args = joinPoint.getArgs();
//			String[] names = ((CodeSignature) sig).getParameterNames();
//			Class<?>[] types = ((CodeSignature) sig).getParameterTypes();
			StringBuffer logMessageStringBuffer = new StringBuffer();

//			for (int i = 0; i < args.length; i++) {
//				logMessageStringBuffer.append("[Name=" + names[i] + " , Type="
//						+ types[i].getName() + " , Value= " + args[i] + "]");
//
//			}
			log.info("Entering method: {} , Argument values: {}",
					sig.getName(), logMessageStringBuffer.toString());
		}
	}

	@AfterReturning("inBusinessDelegateLayer() || inServiceLayer()|| inDomainLayer ()|| inDataAccessLayer()")
	public void logAfterInfo(JoinPoint joinPoint) throws Throwable {
		if (log.isInfoEnabled()) {
			log = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
			Signature sig = joinPoint.getSignature();
			log.info("Successfuly Leaving method: {} ", sig.getName());
		}

	}

}
